package at.donalfonso.ui.group;

import java.io.Serializable;
import java.util.ArrayList;

import org.mozartspaces.capi3.AnyCoordinator;
import org.mozartspaces.capi3.LindaCoordinator;
import org.mozartspaces.capi3.Selector;
import org.mozartspaces.core.Capi;
import org.mozartspaces.core.Entry;
import org.mozartspaces.core.MzsConstants.Container;
import org.mozartspaces.core.MzsCoreException;
import org.mozartspaces.core.MzsConstants.RequestTimeout;

import at.donalfonso.model.LieferBestellung;
import at.donalfonso.model.LieferBestellungStatus;
import at.donalfonso.model.LieferKunde;
import at.donalfonso.model.Pizza.PizzaEnum;
import at.donalfonso.utility.SpaceUtility;

public class BenchmarkController {

	private SpaceUtility filiale1 = null;
	private SpaceUtility filiale2 = null;
	private Capi capi1, capi2;
	
	private ArrayList<LieferBestellung> fertig, nichtfertig;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		int laufzeit;
		if (args.length > 0) {
			laufzeit = Integer.parseInt(args[0]);
		}
		else {
			laufzeit = 60;
		}
		
		BenchmarkController bc = new BenchmarkController();

		try {
			bc.createKunden();
			Thread.sleep(laufzeit * 1000);
			bc.receiveBestellungen();
		} 
		catch (MzsCoreException | InterruptedException e) {
			e.printStackTrace();
		}
		
		bc.printResult();
	}
	
	public BenchmarkController() {

	
		filiale1 = new SpaceUtility(1);
		filiale2 = new SpaceUtility(2);
		capi1 = filiale1.getCapi();
		capi2 = filiale2.getCapi();
		// Eigener Space für Lieferkunden existiert global für alle Filialen
		filiale1.createLieferCore();
		fertig = new ArrayList<LieferBestellung>();
		nichtfertig = new ArrayList<LieferBestellung>();
	
		System.out.println("\nBenchmarkController\n");
	}
		
	public void createKunden() throws MzsCoreException {
		filiale1.getLieferCapi().createContainer("kunde.adresse", filiale1.getLieferUri(), Container.UNBOUNDED, null, new AnyCoordinator());
		LieferKunde lk;
		for (int i=0; i<100; i++) {
			lk = new LieferKunde(1, "adresse", true, PizzaEnum.MARGARITA, PizzaEnum.MARGARITA, PizzaEnum.SALAMI, PizzaEnum.CARDINALE);
			capi1.write(new Entry(lk), filiale1.getTelefonContainer());
		}
		for (int i=0; i<100; i++) {
			lk = new LieferKunde(2, "adresse", true, PizzaEnum.MARGARITA, PizzaEnum.SALAMI, PizzaEnum.CARDINALE, null);
			capi2.write(new Entry(lk), filiale2.getTelefonContainer());
		}
		for (int i=0; i<100; i++) {
			lk = new LieferKunde(2, "adresse", true, PizzaEnum.MARGARITA, PizzaEnum.SALAMI, null, null);
			capi2.write(new Entry(lk), filiale2.getTelefonContainer());
		}
	}

	public void receiveBestellungen() throws MzsCoreException {
		LieferBestellung template = new LieferBestellung();
		Selector sel = LindaCoordinator.newSelector(template, Selector.COUNT_MAX);
		ArrayList<Serializable> ls = new ArrayList<Serializable>();
		ls = capi1.read(filiale1.getSaalContainer(), sel, RequestTimeout.TRY_ONCE, null);
		ls.addAll(capi2.read(filiale2.getSaalContainer(), sel, RequestTimeout.TRY_ONCE, null));
		ls.addAll(capi1.read(filiale1.getBestellungOffenContainer(), sel, RequestTimeout.TRY_ONCE, null));
		ls.addAll(capi2.read(filiale2.getBestellungOffenContainer(), sel, RequestTimeout.TRY_ONCE, null));
		ls.addAll(capi1.read(filiale1.getZustellungContainer(), sel, RequestTimeout.TRY_ONCE, null));
		ls.addAll(capi2.read(filiale2.getZustellungContainer(), sel, RequestTimeout.TRY_ONCE, null));
		ls.addAll(capi1.read(filiale1.getTelefonContainer(), sel, RequestTimeout.TRY_ONCE, null));
		ls.addAll(capi2.read(filiale2.getTelefonContainer(), sel, RequestTimeout.TRY_ONCE, null));

		for (Serializable s: ls) {
			LieferBestellung lb = (LieferBestellung) s;
			if (lb.getLieferstatus() == LieferBestellungStatus.ERFOLGREICH) {
				fertig.add(lb);
			}
			else if (lb.getLieferstatus() == LieferBestellungStatus.VERSCHOBEN) {
				// nichts zu tun, wurden in anderer Filiale bearbeitet
			}
			else {
				nichtfertig.add(lb);
				System.out.println("Nicht fertig: " + lb);
			}
		}
	}
	
	public void printResult() {
		System.out.println("Fertiggestellte Lieferbestellungen:       " + fertig.size());
		System.out.println("Nicht fertiggestellte Lieferbestellungen: " + nichtfertig.size());
	}
	
}
